--[[
Author: wangxiaoyan
Date: 2020-11-03 16:35:36
LastEditTime: 2020-11-27 22:15:04
FilePath: \Lua\View\UILevel\UILevelRecode.lua
--]]

---@class UILevelRecode : UIBase
UILevelRecode = UIBase.New(PanelResNames.UILevelRecode)
local _M = UILevelRecode

local ITEM_COUNT = 12
--- 展示类型 = [攻击，受伤害量，治疗量]
local SHOW_TYPE = { "ATTACK", "BE_INJURED", "DO_HEAL","KILL" }
local SHOW_TYPE_MAP = { ["ATTACK"] = "attack", ["BE_INJURED"] = "beInjured", ["DO_HEAL"] = "heal",["KILL"] = "killTimes" }

function _M.Init(fightType, record, onPlayBegin, onPlayFinished, _replay_type, _foramtion_type ) -- replay_type回放类型或来源
    _M.fightType = fightType or EnumConst.FightTypeConst.DUNGEON
    BattlePlaybackManager.SetFormationType(_foramtion_type)
    _M.replay_type = _replay_type
    ---@type BattleRecord
    _M.record = clone(record)
    _M.onPlayBegin = onPlayBegin
    _M.onPlayFinished = onPlayFinished
    UIBase.Init(_M)
end

-- 创建
function _M:OnCreate()
    self.comObjList = {}
    self.comTitleList = {}
    self.fightRecordList = {}
    self.maxValue = {}
    self.fightCmdList = nil
    self.requesting = false
    self.autoPlayback = false
    self.destroyed = false
    self.btnPlay = self:GetChild("playback")
    self.version = 0;
    self.HeadRectDrawItem = CtrlManager.GetCtrl(PanelNames.HeadRectItem);
    local record = _M.record
    if not record or record.noFight == 2 then
        self.btnPlay.visible = false
    end

    self:BindUI()

    self:RegisterOnClick(self:GetChild("n200"), self.OnBack)
    self:RegisterOnClick(self:GetChild("back"), self.OnBack)
    self:RegisterOnClick(self.btnPlay, self.ClickPlayBack)

end

function _M:OnEnable()
    self:ReceiveLevelBattleDetailRecord(self.record);
    self:Refresh();
    self:RequestFightCmd(false);

end
-- 销毁
function _M:OnDestroy()
    self.comObjList = nil;
    self.comTitleList = nil;
    self.fightRecordList = nil;
    self.maxValue = nil;
    self.recodeType = nil;
    self.fightCmdList = nil;
    self.requesting = false;
    self.autoPlayback = false;
    self.destroyed = true;
end

function _M:Refresh()
    -- title信息
    for index, item in ipairs(self.comTitleList) do
        local parameters = self.titleRecordList[index]
        --local config = logicMgr.HeroManager.GetHeroConfigbyModelId(tonumber(parameters.headIcon))
        --local iconPath = config and config.f_HeroIcon or ""
        local iconPath = logicMgr.SkinManager.GetHeroIconBySkinId1(tonumber(parameters.headIcon))
        self:SetIcon(item.icon, iconPath, EnumConst.ItemShowType.ICON)
        self:SetText(item.name, parameters.name)
        self:SetText(item.power, HelperFunc.FormatResourceNum(parameters.power))
        item.skill.url = EnumConst.AtlasPath.SkillAtlas .. parameters.skill
        item.frame.url = EnumConst.AtlasPath.ICONAtlas .. parameters.picFrame
    end
    local isWin = self.record.win == 1 --and tostring(self.record.attacker.playerId) == logicMgr.HeroManager.GetRoleId();
    self.upWin.visible = isWin
    self.upFaild.visible = not isWin
    self.downWin.visible = not isWin
    self.downFaild.visible = isWin
    self.resultController1.selectedIndex = isWin and 0 or 1;
    self.resultController2.selectedIndex = isWin and 1 or 0;

    if self.fightType == EnumConst.FightTypeConst.GuildBoss then
        self.typeCtrl.selectedIndex = 1;
        self.attackFightList.itemRenderer = function(idx, obj)
            local data = self.fightRecordList[idx + 1];
            self:refreshObj(data, obj);

        end
        self.attackFightList.numItems = 20;

        self.defenderFightList.itemRenderer = function(idx, obj)
            local data = self.fightRecordList[20 + idx + 1];
            self:refreshObj(data, obj);
        end
        self.defenderFightList.numItems = 6;
    else
        self.typeCtrl.selectedIndex = 0;
        -- 数据信息
        for i = 1, ITEM_COUNT do
            local item = self.comObjList[i]
            local data = self.fightRecordList[i]
            self:refreshObj(data, item);
        end
    end
end

function _M:refreshObj(data, go)
    local isShow = data
    local item = go;
    if isShow then
        if self.fightType == EnumConst.FightTypeConst.GuildBoss then
            item = {};
            item.root = go
            item.controller = self:GetController("empty", item.root)
            item.icon = self:GetChild("hero", item.root)
            for index, value in ipairs(SHOW_TYPE) do
                item["process" .. value] = self:GetChild("process" .. index, item.root)
                item["num" .. value] = self:GetChild("num" .. index, item.root)
            end
        end
        for index, value in ipairs(SHOW_TYPE) do
            local num = HelperFunc.Format4ResourceNum(data[value]);
            item["num" .. value].text = value == "KILL" and string.format(getLanguage("LevelRecodeTips"), num) or num;
            local rate = 0
            if data[value] and self.maxValue[value] and self.maxValue[value] > 0 then
                rate = data[value] / self.maxValue[value]
            end
            item["process" .. value].value = rate * 100
        end
        if self.HeadRectDrawItem ~= nil then
            self.HeadRectDrawItem.initData(item.icon, data);
        end
        item.controller.selectedIndex = isShow and 1 or 0

    else
        item = go;
        if type(item) == "table" and item.controller then
            item.controller.selectedIndex = isShow and 1 or 0
        else
            self:GetController("empty", item).selectedIndex = isShow and 1 or 0
        end
    end

end

function _M:RequestFightCmd()
    if self.requesting then
        return ;
    end
    self.requesting = true;
    --- 请求战斗命令
    if self.record.version == GetFightVersion() then

        BattlePlaybackManager.requestFightCmd(self.record, self.fightType, function(fightCmdList)
            self.requesting = false;
            self.fightCmdList = fightCmdList;

            if self.destroyed then
                return ;
            end

            if self.autoPlayback then
                if self.fightCmdList == nil then
                    self.autoPlayback = false;
                    UISysTips.AddMsg(getLanguage("Character_Tips25"));
                else
                    self:Playback();
                end
            end
        end);
    end
end

-- 回放
function _M:ClickPlayBack()
    self.autoPlayback = true;
    if self.record.version ~= GetFightVersion() then
        UISysTips.AddMsg(getLanguage("ErrorCode_220005"));
        return;
    end
    if self.fightCmdList == nil then
        self:RequestFightCmd(true);
        return ;
    end

    self:Playback();
end

function _M:Playback()
    if self.fightCmdList == nil then
        return ;
    end

    self.autoPlayback = false;
    -- FightManager.isRePlay = true;
    FightManager.SetRePlay(true)
    FightManager.SetReplayType(self.replay_type)
    
    BattlePlaybackManager.setBattleRecord(self.record);
    BattlePlaybackManager.setBattleResult(self.record.win);
    if BattlePlaybackManager.getBattleResult() == 1 then
        logicMgr.FubenModel.SetPassTimeForLast(math.floor(HelperFunc.GetServerTime()))
    end
    BattlePlaybackManager.playBattle(self.fightCmdList, self.fightType, function()
        UIBottom.closeAllUI();
        if _M.onPlayBegin ~= nil then
            _M.onPlayBegin();
        end
        closeUI(PanelNames.UILevelRecode);
    end, function()
        if self.fightType == EnumConst.FightTypeConst.DUNGEON then
            --showUI(PanelNames.UIDuplicationDetails)
        elseif self.fightType == EnumConst.FightTypeConst.ARENA then
            local formation_type = logicMgr.BattlePlaybackManager.GetFormationType() 
            showUI(PanelResNames.UIArenaMainEnter);
            local arena_type = 1
            if formation_type and formation_type == EnumConst.FormationType.CrossArenaAtk then
                arena_type = 2
            elseif formation_type and formation_type == EnumConst.FormationType.TeamCrossArenaAtk then
                arena_type = 3
            end
            showUI(PanelNames.UIArenaMain, arena_type)
        elseif self.fightType == EnumConst.FightTypeConst.TOWER then
            --local curTowerType = logicMgr.TowerManager.getClimbType();
            --showUI(PanelNames.UIClimbTower,nil,false,curTowerType)
        elseif self.fightType == EnumConst.FightTypeConst.TRIAL then
            AudioManager.SetSwitch("Battle_SwitchGroup", "stormbay")
            showUI(PanelNames.UIChaosTestNew);
        end
        if _M.onPlayFinished ~= nil then
            _M.onPlayFinished();
        end
    end);
end

--- 整理战报数据
--- @param recordData BattleRecord 战报记录
function _M:ReceiveLevelBattleDetailRecord(recordData)
    self.fightRecordList = {}
    self.maxValue = {}
    self.maxValue.KILL = 6;--最多杀6个人

    --- @type FighterInfo
    local attacker = recordData.attacker;
    --- @type FighterInfo
    local defender = recordData.defender;
    if self.fightType == EnumConst.FightTypeConst.GuildBoss then
        self:CalDataHelper(attacker.members, attacker.memberStats, attacker.formation, 0)
        self:CalDataHelper(defender.members, defender.memberStats, defender.formation, 20)
    else
        self:CalDataHelper(attacker.members, attacker.memberStats, attacker.formation, 0)
        self:CalDataHelper(defender.members, defender.memberStats, defender.formation, ITEM_COUNT * 0.5)
    end

    self.titleRecordList = {}
    self.titleRecordList[1] = {}
    self.titleRecordList[2] = {}
    if G.dataTable["t_skillshow"][tostring(attacker.supportSkillId)] ~= nil then
        self.titleRecordList[1].skill = G.dataTable["t_skillshow"][tostring(attacker.supportSkillId)].f_SkillIcon;
    else
        self.titleRecordList[1].skill = "";
    end
    if G.dataTable["t_skillshow"][tostring(defender.supportSkillId)] ~= nil then
        self.titleRecordList[2].skill = G.dataTable["t_skillshow"][tostring(defender.supportSkillId)].f_SkillIcon;
    else
        self.titleRecordList[2].skill = "";
    end
    self.titleRecordList[1].picFrame = attacker.picFrame == 0 and "800001" or attacker.picFrame;
    self.titleRecordList[2].picFrame = defender.picFrame == 0 and "800001" or attacker.picFrame;
    if self.fightType == EnumConst.FightTypeConst.DUNGEON
            or self.fightType == EnumConst.FightTypeConst.TOWER or self.fightType == EnumConst.FightTypeConst.Expedition
            or self.fightType == EnumConst.FightTypeConst.StoryBattle or self.fightType == EnumConst.FightTypeConst.LongJourneyHell then
        self.titleRecordList[1].name = attacker.playerName or ""
        self.titleRecordList[1].headIcon = attacker.pic or ""
        self.titleRecordList[1].power = attacker.power or ""
        local partnerModelId = self.fightRecordList[ITEM_COUNT * 0.5 + 1].partnerModelId
        self.titleRecordList[2].headIcon = partnerModelId
        self.titleRecordList[2].name = getLanguage(logicMgr.HeroManager.GetHeroConfigbyModelId(partnerModelId).f_HeroName)
        self.titleRecordList[2].power = defender.power or ""
    elseif self.fightType == EnumConst.FightTypeConst.ARENA or self.fightType == EnumConst.FightTypeConst.RankBattle then
        self.titleRecordList[1].name = attacker.playerName or ""
        self.titleRecordList[1].headIcon = attacker.pic or ""
        self.titleRecordList[1].power = attacker.power or ""
        self.titleRecordList[2].name = defender.playerName or ""
        self.titleRecordList[2].headIcon = defender.pic or ""
        self.titleRecordList[2].power = defender.power or ""
    elseif self.fightType == EnumConst.FightTypeConst.TRIAL or self.fightType == EnumConst.FightTypeConst.SoloChaosTest then
        self.titleRecordList[1].name = attacker.playerName or ""
        self.titleRecordList[1].headIcon = attacker.pic or ""
        self.titleRecordList[1].power = attacker.power or ""
        local formation = recordData.defender.members;
        for i = 1, #formation do
            local id = tonumber(tostring(formation[i]));
            if id ~= 0 then
                self.titleRecordList[2].name = getLanguage(logicMgr.HeroManager.GetHeroConfigbyModelId(formation[i].partnerModelId).f_HeroName) or ""
                self.titleRecordList[2].headIcon = formation[i].partnerModelId or "";
                self.titleRecordList[2].power = defender.power or ""
            end
        end
    elseif self.fightType == EnumConst.FightTypeConst.FriendCompeteBattle or self.fightType == EnumConst.FightTypeConst.GuildFriendCompeteBattle or
            self.fightType == EnumConst.FightTypeConst.DungeonEventPK then
        self.titleRecordList[1].name = attacker.playerName or ""
        self.titleRecordList[1].headIcon = attacker.pic or ""
        self.titleRecordList[1].power = attacker.power or ""

        self.titleRecordList[2].name = defender.playerName or ""
        self.titleRecordList[2].headIcon = defender.pic or ""
        self.titleRecordList[2].power = defender.power or ""
    elseif self.fightType == EnumConst.FightTypeConst.Plunder or self.fightType == EnumConst.FightTypeConst.GuildBattlePlus then
        self.titleRecordList[1].name = attacker.playerName or ""
        self.titleRecordList[1].headIcon = attacker.pic or ""
        self.titleRecordList[1].power = attacker.power or ""
        self.titleRecordList[2].name = defender.playerName or ""
        self.titleRecordList[2].headIcon = defender.pic or ""
        self.titleRecordList[2].power = defender.power or ""
    elseif self.fightType == EnumConst.FightTypeConst.GuildBoss then
        self.titleRecordList[1].name = attacker.playerName or ""
        self.titleRecordList[1].headIcon = attacker.pic or ""
        self.titleRecordList[1].power = attacker.power or ""
        local formation = recordData.defender.members;
        for i = 1, #formation do
            local id = tonumber(tostring(formation[i]));
            if id ~= 0 then
                self.titleRecordList[2].name = getLanguage(logicMgr.HeroManager.GetHeroConfigbyModelId(formation[i].partnerModelId).f_HeroName) or ""
                self.titleRecordList[2].headIcon = formation[i].partnerModelId or "";
                self.titleRecordList[2].power = defender.power or ""
            end
        end
    end

    self:Refresh()
end

--- 计算战斗数据
--- @param members table<number, FighterMemberInfo>
--- @param statistics table<number, MemberStat>
--- @param baseOffset number
function _M:CalDataHelper(members, statistics, formation, baseOffset)
    local i = 1;
    local allCount = ITEM_COUNT * 0.5;
    if self.fightType == EnumConst.FightTypeConst.GuildBoss then
        if baseOffset == 0 then
            allCount = 20;
        else
            allCount = 6
        end
    end

    for indexx = 1, allCount do
        local id = tonumber(tostring(formation[indexx]));
        if id ~= 0 then
            local value = members[i]
            if value then
                local item = {}
                self.fightRecordList[baseOffset + indexx] = item
                item.partnerModelId = value.partnerModelId
                self.heroData = logicMgr.HeroManager.getHeroDatabyModelId(value.partnerModelId, true);
                item.level = value.level
                item.star = value.star
                item.icon = self.heroData.icon
                item.type = self.heroData.type
                item.weaponLevel = value.weaponLevel
                item.skinId = value.useSkinId
                local statistic = statistics[i]
                for index, value in ipairs(SHOW_TYPE) do
                    item[value] = int64ToNumber(statistic[SHOW_TYPE_MAP[value]]) or 0

                    if self.maxValue[value] == nil then
                        self.maxValue[value] = 0
                    end
                    if item[value] > self.maxValue[value] then
                        self.maxValue[value] = item[value]
                    end
                end
            end
            i = i + 1;
        end
    end
end

function _M:BindUI()
    local myTitle = {}
    table.insert(self.comTitleList, myTitle)
    myTitle.name = self:GetChild("myName")
    myTitle.icon = self:GetChild("myHead/head/HeadIcon")
    myTitle.frame = self:GetChild("myHead/frame")
    myTitle.power = self:GetChild("power")
    myTitle.skill = self:GetChild("supSkillP1"):GetChild("Mask"):GetChild("Icon")
    local eTitle = {}
    table.insert(self.comTitleList, eTitle)
    eTitle.name = self:GetChild("eName")
    eTitle.icon = self:GetChild("eHead/head/HeadIcon")
    eTitle.frame = self:GetChild("eHead/frame")
    eTitle.power = self:GetChild("powerEnemy")
    eTitle.skill = self:GetChild("supSkillP2"):GetChild("Mask"):GetChild("Icon")
    self.upWin = self:GetChild("upWin")
    self.upFaild = self:GetChild("upFaild")
    self.downWin = self:GetChild("downWin")
    self.downFaild = self:GetChild("downFaild")
    self.resultController1 = self:GetChild("bg1"):GetController("result");
    self.resultController2 = self:GetChild("bg2"):GetController("result");
    self.attackFightList = self:GetChild("attackFightList");--攻击方列表
    self.defenderFightList = self:GetChild("defenderFightList");--防守方列表
    self.typeCtrl = self:GetController("type")
    if self.fightType == EnumConst.FightTypeConst.GuildBoss then

    else
        for i = 1, ITEM_COUNT do
            local item = {}
            local path = "record" .. i
            item.root = self:GetChild(path)
            item.controller = self:GetController("empty", item.root)
            item.icon = self:GetChild("hero", item.root)
            for index, value in ipairs(SHOW_TYPE) do
                item["process" .. value] = self:GetChild("process" .. index, item.root)
                item["num" .. value] = self:GetChild("num" .. index, item.root)
            end
            table.insert(self.comObjList, item)
        end
    end
end

return _M
